﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Com.ContentRendering.Api.ParserEngine;

namespace Com.ContentRendering.Api.ParserEngineComponentTest.Helper
{
    internal class OutputNodeHelper : OutputNodeInterface
    {
        XmlNode _xmlNode;

        internal OutputNodeHelper()
        {
            XmlDocument xmlDocument = new XmlDocument();

            this._xmlNode = xmlDocument.CreateElement("document");
            xmlDocument.AppendChild(this._xmlNode);
        }

        internal OutputNodeHelper(XmlNode xmlNode)
        {
            this._xmlNode = xmlNode;
        }

        public OutputNodeInterface AddRootSubstitutionTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagRootSubstitution");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddRootTransparentTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagRootTransparent");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddRootIfTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagRootIf");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddRootIfNotTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagRootIfNot");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public void AddRootOutputTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagRootOutput");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);
        }

        public OutputNodeInterface AddChildSubstitutionTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagChildSubstitution");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddChildTransparentTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagChildTransparent");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddChildIfTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagChildIf");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddChildIfNotTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagChildIfNot");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public void AddChildOutputTag(string name)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagChildOutput");
            XmlAttribute xmlNameAttribute = this._xmlNode.OwnerDocument.CreateAttribute("name");

            xmlNameAttribute.Value = name;

            childXmlNode.Attributes.Append(xmlNameAttribute);
            this._xmlNode.AppendChild(childXmlNode);
        }

        public OutputNodeInterface AddParentSubstitutionTag(int level)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagParentSubstitution");
            XmlAttribute xmlLevelAttribute = this._xmlNode.OwnerDocument.CreateAttribute("level");

            xmlLevelAttribute.Value = level.ToString();

            childXmlNode.Attributes.Append(xmlLevelAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddParentTransparentTag(int level)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagParentTransparent");
            XmlAttribute xmlLevelAttribute = this._xmlNode.OwnerDocument.CreateAttribute("level");

            xmlLevelAttribute.Value = level.ToString();

            childXmlNode.Attributes.Append(xmlLevelAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddParentIfTag(int level)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagParentIf");
            XmlAttribute xmlLevelAttribute = this._xmlNode.OwnerDocument.CreateAttribute("level");

            xmlLevelAttribute.Value = level.ToString();

            childXmlNode.Attributes.Append(xmlLevelAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public OutputNodeInterface AddParentIfNotTag(int level)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagParentIfNot");
            XmlAttribute xmlLevelAttribute = this._xmlNode.OwnerDocument.CreateAttribute("level");

            xmlLevelAttribute.Value = level.ToString();

            childXmlNode.Attributes.Append(xmlLevelAttribute);
            this._xmlNode.AppendChild(childXmlNode);

            return new OutputNodeHelper(childXmlNode);
        }

        public void AddParentOutputTag(int level)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("tagParentOutput");
            XmlAttribute xmlLevelAttribute = this._xmlNode.OwnerDocument.CreateAttribute("level");

            xmlLevelAttribute.Value = level.ToString();

            childXmlNode.Attributes.Append(xmlLevelAttribute);
            this._xmlNode.AppendChild(childXmlNode);
        }

        public void AddContent(string content)
        {
            XmlNode childXmlNode = this._xmlNode.OwnerDocument.CreateElement("content");

            // the test code needs to check against whitespace which will get lost if its not encoded
            string encodedContent = content.Replace("\r\n", "\\r\\n");

            childXmlNode.InnerText = encodedContent;

            this._xmlNode.AppendChild(childXmlNode);
        }

        public OutputNodeInterface Parent
        {
            get
            {
                // return null if the node is the document
                if (this._xmlNode.Name == "document")
                {
                    return null;
                }

                return new OutputNodeHelper(this._xmlNode.ParentNode);
            }
        }

        public override string ToString()
        {
            return this._xmlNode.OwnerDocument.OuterXml;
        }

    }
}
